#Constrctor for a simple male snow crab. This object will become more complex as more data and fuctionality
#are added. The male crab currently stores its parent, its position in its parents list, its size, heading and
#displacement rate 
setConstructorS3("ASCmale", function(lispos = "", size = 0, parent = "") {
	# Extends RAgent object
	extend(RAgent(), "ASCmale",
		.lispos = lispos, #Position in parents list
	    .parent = parent, #parent SnowCrab object
		
		.size = size, #random fake value
		.hding = bfunc(runif(1)), #Heading at this value of bfunc
		.vel = mfunc(runif(1)) #Displacement at this value of mfunc, #km per day
	   
	)
})

#This is the do method of the male snow crab.  
setMethodS3("do", "ASCmale", function(this, mes, fro) {
	#This is to test that a crab will not do daily opertions twice, may want to comment out
	if( this$.parent$.updated == this$.updated) print("I will not do daily actions as I was already visited today")
	
	#If the message is plusDay the SnowCrab object is telling the male snow crab that a day has passed
	#And it needs to do its daily routines. This should only happen if it has not already 
	#been told that a day has passed. It checks this with this$.parent$.updated != this$.updated 
	#if true it changes its .updated variable and can no longer be entered untill another day has passed
	if(mes == "plusDay" && this$.parent$.updated != this$.updated){
		this$.updated = this$.updated * -1 #Change to tell that its day is up to date
	    this$.dayspassed = this$.dayspassed + 1 #Increment day, may later be mtched to a snow crab year cycle object 
		print(paste("I am an individual crab and ", this$.dayspassed, " days have passed, moving by daily displacement"))
	    this$move() #Move crab Every day 
	}
})

#Move method rules that are unique to a male snow crab 
setMethodS3("move", "ASCmale", function(this) {

	newlo <- this$getlo() + (sin(this$.hding)*this$.vel) #Get projected new longnitude location
    newla <- this$getla() + (cos(this$.hding)*this$.vel) #Get projected new latitude location
		
	cboun = this$.parent$.homecell$.geography #Get the cells boundary
	
	##if move will go ouside of environment boundary, change heading and
	##add command to this crab to try to move again.

	if(newlo >= max(bndary[,1]) || newlo <= min(bndary[,1]) || newla >= max(bndary[,2]) || newla <= min(bndary[,2])) { 
		print("My new location puts me out of environment, Ajusting parameters and trying again")
		print(paste("my old location:", this$getlo(), " ", this$getla()))
		print(paste("my new location:", newlo, " ", newla))
		this$.hding = bfunc(runif(1))
		this$.vel = this$.vel
	    this$move()
	}
    #Outside this cell so add the crab to new cell and remove from this one	
	else if(newlo <= min(cboun[,1]) || newlo >= max(cboun[,1]) || newla >= max(cboun[,2]) || newla <= min(cboun[,2])){
		logriloc = ceiling(newlo/celwid)
		lagriloc = ceiling(newla/celhei)
		print("My new location puts me in a new cell")
		print(paste("my old location:", this$getlo(), " ", this$getla()))
		print(paste("my new location:", newlo, " ", newla))
		this$setgeo(matrix(c(newlo, newla), ncol = 2, nrow = 1))
		
		
		this$send("remthisSCmale", this$.parent)
		this$send("addthisSCmale", this$.parent$.homecell$.parent$.cells[[lagriloc]][[logriloc]]$.li[["SnowCrab"]])
		
		
	}
    
	
	##Inside boundary so update crabs new position
    else{	
		this$setgeo(matrix(c(newlo, newla), ncol = 2, nrow = 1))
    }
})